package com.aioz.security.aop;

import com.aioz.security.entity.Log;
import com.aioz.security.entity.LoginUser;
import com.aioz.security.service.impl.LogServiceImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.time.LocalDateTime;

@Aspect
@Component
public class LogInfoAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogInfoAspect.class);

    @Resource
    private LogServiceImpl logService;

    /**
     * @annotation 中的路径表示拦截特定注解
     */
    @Pointcut("@annotation(com.aioz.security.aop.annotation.LogInfoAnnotation)")
    public void logInfoPC() {
    }

    @Around("logInfoPC()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        /*
         定义开始时间
        * */
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();
        //获取操作
        Log log = new Log();
        log.setMethod(method.getName());
        Long userId = getCurrentUserId();
        if(null == userId){
            log.setUserId(0);
        }else {
            log.setUserId(Math.toIntExact(userId));
        }
        log.setCreateTime(LocalDateTime.now());
        log.setStatusCode(200);
        Object result = null;
        try {
            // 执行业务操作
            result = pjp.proceed();
        }catch (Exception e){
            logger.error(e.getMessage());
            log.setMessage(e.getMessage());
            log.setStatusCode(501);
            throw e;
        }finally {
            logService.save(log);
        }
        return result;
    }

    public Long getCurrentUserId(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        return loginUser.getUser().getId();
    }
}
